package org.ph.share.lock.test.thread2;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

/**
 * 生产消费设计模式
 *
 * @author Hush.
 * @since 2023/5/18 18:14
 */
@Slf4j
public class Thread5 {
    public static void main(String[] args) {
        // 初始化MessageQueue
        MessageQueue messageQueue = new MessageQueue(5);
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            new Thread(() -> messageQueue.put(new Message(finalI, "hello,i am producer." + finalI)), "生产" + i).start();
        }


        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                Message take = messageQueue.take();
                log.info("获取消息：{}", take);
            }
        }, "消费").start();
    }
}

/**
 * 基于线程的消息队列实践
 *
 * @author Hush.
 * @since 2023/5/18 18:30
 */
@Slf4j
class MessageQueue {

    // 容器
    private final LinkedList<Message> container = new LinkedList<>();

    // 容量
    private final int capacity;

    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    // 存_放在链表后位
    public void put(Message mes) {
        synchronized (container) {
            while (container.size() == capacity) {
                try {
                    log.info("到达容量上限");
                    container.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            container.addFirst(mes);
            log.info("已存入消息：{}", mes);
            container.notifyAll();

        }
    }

    // 取_取先入的mess对象
    public Message take() {
        synchronized (container) {
            while (container.isEmpty()) {
                try {
                    container.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            container.notifyAll();
            return container.removeLast();
        }
    }
}

/**
 * 消息对象
 *
 * @author Hush.
 * @since 2023/5/18 18:17
 */
final class Message {
    /**
     * 唯一
     */
    private final int id;
    /**
     * 消息
     */
    private final Object mess;

    public Message(int id, Object mess) {
        this.id = id;
        this.mess = mess;
    }

    public int getId() {
        return id;
    }

    public Object getMess() {
        return mess;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", mess=" + mess +
                '}';
    }
}